//
// Created by TATO on 2025/8/13.
//
#include "app_evnet_list.h"
#include <unix/http_code.h>
#include <http_req_rep_com.h>
#include "http_tcp.h"
struct port_ev_container {
    dts head;
    dts body;
    struct http_socket_event_s *hset;
    char buf[BUF_SIZE];
    struct responseContext *response;
    before_response_callback bf_callback;
    running_response_callback ru_callback;
    after_response_callback af_callback;
};

int _recv_stream(struct http_socket_event_s *hset, int fd, char* buf, int len)
{
    int r_len = Recv(hset->logs, fd, buf, len);
    if (r_len == 0) {
        error(hset->logs, "The end-to-end service has been closed: %d", fd);
        return -1;
    } else if (r_len < 0) {
        if(errno == EAGAIN || errno == EWOULDBLOCK){
            return 0;
        }else if(errno == ECONNRESET || errno == ECONNREFUSED) {
            error(hset->logs, "An existing connection was forcibly closed by the remote host: %s", strerror(errno));
        }else if(errno == ECONNABORTED) {
            error(hset->logs, "An established connection was aborted by the software in your host machine.: %s", strerror(errno));
        }else if(errno == EINTR) {
            error(hset->logs, "System call interrupted by signal: %s", strerror(errno));
        }else {
            error(hset->logs, "_recv_stream(): Other errors: %s", strerror(errno));
        }
        return -1;
    }
    return r_len;
}

int _send_stream(struct http_socket_event_s *hset, int fd, char* buf, int len){
    int total_send = 0;
    while (total_send < len) {
        if(!fd_is_connected(fd)){
            error(hset->logs, "%d,%d: The current TCP is in a disconnected state: %s", fd, errno, strerror(errno));
            if(errno == 9)
                error(hset->logs, "err %d", fd);
            return -2;
        }
        int s_len = Write(hset->logs, fd, buf + total_send, len - total_send);
        if(s_len == -1){
            if (errno == EAGAIN || errno == EWOULDBLOCK) {
                continue;
            }
            error(hset->logs, "Other errors: %d : %s", errno, strerror(errno));
            return -1;
        } else{
            total_send += s_len;
        }
    }
    return total_send;
}

int _clear_read_buf(struct http_socket_event_s *hset, int fd) {
    char buffer[BUF_SIZE];
    int bytes_read;
    while ((bytes_read = vgetData(hset->logs, fd, buffer, sizeof(buffer))) > 0) {
        // 使用MSG_PEEK标志，数据不会从套接字接收队列中移除
        _recv_stream(hset, fd, buffer, bytes_read); // 实际读取数据并移除
    }
    if(bytes_read < 0) {
        reset_conn_fd(hset, fd);
    }
}

void closeClient(struct port_ev_container* port_ev_c){
    debug(port_ev_c->hset->logs, "%s[%d][%d]", "http请求处理完成!!", port_ev_c->response->fd,port_ev_c->response->client_fd);
    s_del_event(port_ev_c->response->hset->ev_container, &port_ev_c->response->hset->ev_c_lock, port_ev_c->response->client_fd, IO_ADD_RD_EVENT);
    if(port_ev_c->response->fd_errno != EBADF) {
        unlock_client_fd(port_ev_c->hset, port_ev_c->response->fd);
    }
    if(port_ev_c->response->client_fd_errno != EBADF) {
        _clear_read_buf(port_ev_c->hset, port_ev_c->response->client_fd);
        unlock_conn_fd(port_ev_c->hset, port_ev_c->response->client_fd);
    }
    dts_free_null(&port_ev_c->head);
    dts_free_null(&port_ev_c->body);
    http_free_null(&port_ev_c->response->attr);
    http_free_null(&port_ev_c->response);
    http_free_null(&port_ev_c);
}

int _rep_send_control_do(struct port_ev_container *port_ev_c, char* buf, int len, dts* head) {
    int index, res;
    if(!port_ev_c->response->head){
        if(!*head)
            *head = dtsempty();
        int h_len = strlen(*head);
        *head = dtscatlen(*head, port_ev_c->buf, len);
        if((index = indexof(*head, HEAD_TAIL)) > -1){
            (*head)[index + strlen(HEAD_TAIL)] = '\0';
            port_ev_c->response->head = *head;
            port_ev_c->response->buf = *head;
            int head_len = (index + strlen(HEAD_TAIL));

            if(index > 10000){
                info(port_ev_c->hset->logs, "[%d]%s", index, *head);
            }
            port_ev_c->bf_callback(port_ev_c->response);
            port_ev_c->ru_callback(port_ev_c->response);
            res = _send_stream(port_ev_c->response->hset, port_ev_c->response->fd, *head, strlen(*head));
            if(res <= 0) {
                port_ev_c->response->rep_stream.read_end = 1;
                port_ev_c->response->fd_errno = errno;
            }
            if (port_ev_c->response->rep_stream.read_end == 1){
                port_ev_c->af_callback(port_ev_c->response);
                dts_free_null(&port_ev_c->response->head);
                dts_free_null(&port_ev_c->response->prev_buf);
                return 0;
            }
            port_ev_c->response->prev_buf = dtsdup(*head);
            int buf_tail_idx = head_len - h_len;
            buf = buf + buf_tail_idx;
            len = len - buf_tail_idx;
        }else
            return 0;
    }
    port_ev_c->response->buf = buf;
    port_ev_c->response->buf_len = len;
    port_ev_c->ru_callback(port_ev_c->response);
    res = _send_stream(port_ev_c->response->hset, port_ev_c->response->fd, buf, len);
    if(res <= 0) {
        port_ev_c->response->rep_stream.read_end = 1;
        port_ev_c->response->fd_errno = errno;
    }
    if (port_ev_c->response->rep_stream.read_end == 1){
        port_ev_c->af_callback(port_ev_c->response);
        dts_free_null(&port_ev_c->response->head);
        dts_free_null(&port_ev_c->response->prev_buf);
        return 0;
    }
    dts_free_null(&port_ev_c->response->prev_buf);
    port_ev_c->response->prev_buf = dtsnew(port_ev_c->response->buf);
    return 0;
}

// 处理客户端发送来的数据
void client_read_fd_handler(event_container_t *ec, event_p_t* e_param) {   // 循环查询select容器
    int client_fd = e_param->fd;
    struct port_ev_container *port_ev_c = (struct port_ev_container *) e_param->args;
    dts headstr = NULL;
if(client_fd > 500){
    fprintf(stderr, "client_fd err:[%d]", client_fd);

    return;
}
    while(1){
        memset(port_ev_c->buf, 0, sizeof(port_ev_c->buf));
        ssize_t len = _recv_stream(port_ev_c->response->hset, client_fd, port_ev_c->buf, (sizeof port_ev_c->buf) - 1);
        if(len == 0){
            return;
        }
        if(len < 0) {
            port_ev_c->response->rep_stream.read_end = 1;
            port_ev_c->af_callback(port_ev_c->response);
            closeClient(port_ev_c);
            return;
        } else {
            _rep_send_control_do(port_ev_c, port_ev_c->buf, len, &headstr);
            if(port_ev_c->response->rep_stream.read_end) {
                closeClient(port_ev_c);
                return;
            }
        }
    }
}

// 处理客户端发送来的数据
void client_write_fd_handler(event_container_t *ec, event_p_t *e_param) {
    int client_fd = e_param->fd;
    struct port_ev_container *port_ev_c = (struct port_ev_container *) e_param->args;

    int res = _send_stream(port_ev_c->response->hset, client_fd, port_ev_c->head, strlen(port_ev_c->head));
    if (res <= 0) {
        if(res == -2) {
            reset_conn_fd(port_ev_c->response->hset, client_fd);
        }
        port_ev_c->response->client_fd_errno = errno;
        closeClient(port_ev_c);
        return;
    }

    if(port_ev_c->body) {
        res = _send_stream(port_ev_c->response->hset, client_fd, port_ev_c->body, strlen(port_ev_c->body));
        if (res <= 0) {
            if(res == -2) {
                reset_conn_fd(port_ev_c->response->hset, client_fd);
            }
            port_ev_c->response->client_fd_errno = errno;
            closeClient(port_ev_c);
            return;
        }
    }
}

void event_io(struct requestContext *request, before_response_callback bf_callback, running_response_callback ru_callback, after_response_callback af_callback){
    struct port_ev_container* port_ev_c = (struct port_ev_container*)http_malloc(sizeof (struct port_ev_container));  // free()
    struct response_head_attr_s* attr = (struct response_head_attr_s*) http_malloc(sizeof (struct response_head_attr_s)); //free()
    struct responseContext* response = (struct responseContext*) http_malloc(sizeof (struct responseContext)); //free()

    init_rep_attr(attr);
    init_rep(response);
    response->fd = request->fd;
    response->attr = attr;
    response->hset = request->hset;

    memset(port_ev_c->buf, 0, sizeof(port_ev_c->buf));
    port_ev_c->response = response;
    port_ev_c->head = request->head; // free()
    port_ev_c->body = request->body; // free()
    port_ev_c->hset = request->hset;
    port_ev_c->bf_callback = bf_callback;
    port_ev_c->ru_callback = ru_callback;
    port_ev_c->af_callback = af_callback;

    struct http_server_http_connect_fd_s fds = random_conn_fd(port_ev_c->hset);
    response->client_fd = fds.fd;
    if(!response->client_fd) {
       response->client_fd_errno = errno;
    }
    s_add_event(request->hset->ev_container, &request->hset->ev_c_lock, response->client_fd , IO_ADD_WT_EVENT, client_write_fd_handler, port_ev_c, 1);
    s_add_event(request->hset->ev_container, &port_ev_c->response->hset->ev_c_lock, response->client_fd, IO_ADD_RD_EVENT, client_read_fd_handler, port_ev_c, -1);
    triggerIo(request->hset->ev_container);
}
int port_system_app(struct requestContext *request, before_response_callback bf_callback, running_response_callback ru_callback, after_response_callback af_callback) {
    event_io(request, bf_callback, ru_callback, af_callback);
}